<?php
namespace App\Http\Controllers\Api\Activity;

use DB;

use Carbon\Carbon;

use Illuminate\Http\Request;

use App\Service\CardService;

use App\Models\Card\CardCoupon;

use App\Service\LockingService;

use App\Models\Customer\Customer;

use App\Models\Card\CardCouponCode;

use App\Http\Controllers\Controller;

use App\Models\Activity\Jd\Jd;

use App\Models\Activity\Jd\JdPrize;

use App\Models\Activity\Jd\JdCustomer;

use App\Models\Activity\Jd\JdCustomerCard;

use App\Models\Activity\Jd\JdCustomerDonation;

use App\Models\Activity\Jd\JdCustomerExchange;

use Illuminate\Support\Facades\Redis as Redis;

class JdController extends Controller
{

    /**
     * 集点活动列表
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function init( Request $request )
    {

        $platform = $request->input('platform',6);
        $session_id = $request->input('session_id');
        if ( !$session_id ) {
            $session_id = session_id();
            if (empty($session_id)) {
                return response()->json(['code' => 10000, 'message' => '缺少参数：session_id']);
            }
        }

        $jd_list_redis_index = 'WDH_JD_LIST';

        $jd_count = Redis::zCard($jd_list_redis_index); //检查集点数量

        if ($jd_count == 0) {

            //集点数据
            $where = [];
            $where[] = ['start_time','<=',Carbon::now()];
            $where[] = ['end_time','>=',Carbon::now()];
            $where[] = ['useFlg','=',1];

            /**
             * 根据活动id字段从大到小查询数据
             */
            $jd_list = Jd::select('activity_id')->where($where)->orderBy('activity_id', 'desc')->get()->toArray();
            if ($jd_list) {
                $jd_count = 0;
                foreach ($jd_list as &$jd) {
                    Redis::zAdd( $jd_list_redis_index , $jd_count, $jd['activity_id']);
                    $jd_count++;
                }
                Redis::expire($jd_list_redis_index, 7200); //设置过期时间为2小时
            }
        }
        if ( $jd_count == 0) {
            return response()->json(['code' => 10002 , 'message' => '当前没有集点活动' ]);
        }

        /**
         * 获取集点数据
         */
        $jd_list = Redis::zRange($jd_list_redis_index,0, -1 );
        if (!$jd_list) {
            return response()->json([ 'code' => 10003, 'message' => '当前没有集点活动' ]);
        }

        //查询会员信息
        $pcust_id = get_customer_id( $session_id , $platform );

        $data = [];

        foreach ( $jd_list as &$id ) {

            //获取redis缓存的集点详情信息
            $jd_cache = Jd::getCache( $id );
            if ( !$jd_cache ) {
                continue;
            }
            if ( $jd_cache['useFlg'] == 0 ) {
                continue;
            }
            if ( $jd_cache['end_time'] < Carbon::now() ) {
                continue;
            }

            $have_num = 0; //用户拥有未使用的点数
            if ( $pcust_id ) {

                $customer = JdCustomer::select('not_used_num')->where(['activity_id' => $id, 'pcustID' => $pcust_id])->first();
                if ( $customer ) {
                    $have_num = $customer->not_used_num;
                }

            }

            $data[] = [
                'id' => app_to_int($id),
                'pic' => $request->getSchemeAndHttpHost().$jd_cache['activity_pic'],
                'name' => $jd_cache['activity_name'],
                'start_time' => date('Y/m/d',strtotime( $jd_cache['start_time'] )),
                'end_time' => date('Y/m/d',strtotime( $jd_cache['end_time'] )),
                'jd_num' => app_to_int( $jd_cache['jd_num'] ),
                'have_num' => app_to_int( $have_num ),
            ];

        }

        return response()->json(['code' => 200 , 'message' => 'ok' , 'data' => $data ]);

    }


    /**
     * 集点详情
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function detail( Request $request )
    {

        $activity_id = $request->input('id',0);
        $platform = $request->input('platform',6);
        $session_id = $request->input('session_id');
        if ( !$session_id ) {
            $session_id = session_id();
            if (empty($session_id)) {
                return response()->json(['code' => 10000, 'message' => '缺少参数：session_id']);
            }
        }

        if ( !ebsig_is_int( $activity_id ) ) {
            return response()->json(['code' => 10001 , 'message' => '缺少活动id']);
        }

        //查询会员信息
        $pcust_id = get_customer_id( $session_id , $platform );
        $jd_cache = Jd::getCache( $activity_id );
        if ( empty( $jd_cache ) ) {
            return response()->json(['code' => 10003 , 'message' => '活动不存在']);
        }


        $state = 1;         //活动状态  0、未开始  1、进行中  2、已结束
        if ( $jd_cache['useFlg'] == 0 || $jd_cache['end_time'] < Carbon::now() ) {
            $state = 2;
        } else if ( $jd_cache['start_time'] > Carbon::now() ) {
            $state = 0;
        }

        $have_num = 0;      //会员未使用的集点数
        if ( $pcust_id && $state ) {
            $customer = JdCustomer::select('not_used_num')->where(['activity_id' => $activity_id, 'pcustID' => $pcust_id])->first();
            if ( $customer ) {
                $have_num = $customer->not_used_num;
            }
        }

        $data = [
            'id' => app_to_int( $activity_id ),
            'pic' => $request->getSchemeAndHttpHost().$jd_cache['activity_pic'],
            'name' => $jd_cache['activity_name'],
            'state' => $state,
            'start_time' => date('Y/m/d' , strtotime( $jd_cache['start_time'] )),
            'end_time' => date('Y/m/d' , strtotime( $jd_cache['end_time'] )),
            'jd_num' => app_to_int( $jd_cache['jd_num'] ),
            'have_num' => app_to_int( $have_num ),
            'remark' => nl2br($jd_cache['remark']),
            'show_pic' => $request->getSchemeAndHttpHost().$jd_cache['show_pic'],
            'show_pic_highlight' => $request->getSchemeAndHttpHost().$jd_cache['show_pic_highlight'],
            'is_give' => app_to_int( $jd_cache['is_give'] ),
            'show_type' => app_to_int( $jd_cache['show_type'] ),
        ];

        return response()->json(['code' => 200 , 'message' => 'ok' , 'data' => $data ]);

    }

    /**
     * 转赠页
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function give( Request $request )
    {

        $activity_id = $request->input('id',0);
        $platform = $request->input('platform',6);
        $session_id = $request->input('session_id');
        if ( !$session_id ) {
            $session_id = session_id();
            if (empty($session_id)) {
                return response()->json(['code' => 10000, 'message' => '缺少参数：session_id']);
            }
        }

        if ( !ebsig_is_int( $activity_id ) ) {
            return response()->json(['code' => 10001 , 'message' => '缺少活动id']);
        }

        //查询会员信息
        $pcust_id = get_customer_id( $session_id , $platform );
        if ( !$pcust_id ) {
            return response()->json(['code' => 10002 , 'message' => '未登录']);
        }

        $jd_cache = Jd::getCache( $activity_id );
        if ( empty( $jd_cache ) ) {
            return response()->json(['code' => 10003 , 'message' => '活动不存在']);
        }


        $state = 1;         //活动状态  0、未开始  1、进行中  2、已结束
        if ( $jd_cache['useFlg'] == 0  || $jd_cache['end_time'] < Carbon::now() ) {
            $state = 2;
        } else if ( $jd_cache['start_time'] > Carbon::now() ) {
            $state = 0;
        }

        $have_num = 0; //会员未使用的集点数
        if ( $state ) {
            $customer = JdCustomer::where(['activity_id' => $activity_id, 'pcustID' => $pcust_id])->first();
            if ( $customer  ) {
                $have_num = $customer->not_used_num;
            }
        }

        $data = [
            'id' => app_to_int( $activity_id ),
            'name' => $jd_cache['activity_name'],
            'state' => $state,
            'end_time' => date('Y/m/d', strtotime( $jd_cache['exchange_end_time'] )),
            'have_num' => app_to_int( $have_num )
        ];

        return response()->json(['code' => 200 , 'message' => 'ok' , 'data' => $data ]);

    }

    /**
     * 转赠
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function giveSend ( Request $request ) 
    {

        $give_num = $request->input('give_num',0);
        $give_message = $request->input('give_message','');
        $give_user = $request->input('give_user','');
        $activity_id = $request->input('id',0);
        $platform = $request->input('platform',6);
        $session_id = $request->input('session_id');
        if ( !$session_id ) {
            $session_id = session_id();
            if (empty($session_id)) {
                return response()->json(['code' => 10000, 'message' => '缺少参数：session_id']);
            }
        }
        if ( !ebsig_is_int( $activity_id ) ) {
            return response()->json(['code' => 10001 , 'message' => '缺少活动id']);
        }
        if ( !$give_num ){
            return response()->json(['code' => 10002 , 'message' => '缺少转赠点数']);
        }
        if ( !$give_user ) {
            return response()->json(['code' => 10003 , 'message' => '缺少转赠对象']);
        }

        //查询会员信息
        $cust_data = get_customer_login( $session_id , $platform );
        $pcust_id = $cust_data['pcustID'];
        $cust_id = $cust_data['custID'];
        if ( !$pcust_id ) {
            return response()->json(['code' => 10004 , 'message' => '未登录']);
        }
        if ( $cust_id == $give_user ) {
            return response()->json(['code' => 10013 , 'message' => '不能转增给本人']);
        }

        $jd_cache = Jd::getCache( $activity_id );
        if ( empty( $jd_cache ) ) {
            return response()->json(['code' => 10005 , 'message' => '活动不存在']);
        }
        if ( $jd_cache['useFlg'] == 0 ) {
            return response()->json(['code' => 10006 , 'message' => '活动被禁用']);
        }
        if ( $jd_cache['start_time'] > Carbon::now() ) {
            return response()->json(['code' => 10007 , 'message' => '活动未开始']);
        }
        if ( $jd_cache['end_time'] < Carbon::now() ) {
            return response()->json(['code' => 10013 , 'message' => '活动已结束']);
        }
        if ( !$jd_cache['is_give'] ) {
            return response()->json(['code' => 10008 , 'message' => '该活动不可转赠']);
        }

        //加锁redis
        $redis_index = 'WDH_JD_LOCK_' . $activity_id . '_' . $pcust_id;
        if ( LockingService::check( $redis_index ) ) {
            return response()->json(['code' => 10020 , 'message' => '请求频繁']);
        }

        //检查会员可转赠点数
        $customer = JdCustomer::where(['activity_id' => $activity_id, 'pcustID' => $pcust_id])->first();
        if ( empty( $customer ) ) {
            LockingService::remove();
            return response()->json(['code' => 10009 , 'message' => '当前用户没有可转赠的点数']);
        }
        if ( $give_num > $customer->not_used_num ) {
            LockingService::remove();
            return response()->json(['code' => 10010 , 'message' => '转赠点数不足']);
        }

        //查询转赠会员信息
        $give_customer = Customer::where(['custID' => $give_user])->first();
        if (!$give_customer) {
            LockingService::remove();
            return response()->json(['code' => 10011 , 'message' => '转赠对象不是网站会员']);
        }

        try {

            //开始事务
            DB::beginTransaction();

            //更新会员可用点数
            $where = [
                ['activity_id' , '=' , $activity_id ],
                ['pcustID' , '=' , $pcust_id ],
                ['not_used_num' , '>=' , $give_num]
            ];
            $result = JdCustomer::where($where)->decrement('not_used_num', $give_num);
            if ( !$result ) {
                throw new \Exception('集点扣除失败', 400);
            }

            $result = JdCustomer::where($where)->decrement('total_num', $give_num);
            if ( !$result ) {
                throw new \Exception('集点扣除失败', 400);
            }

            //保存转赠集点
            $customer_obj = JdCustomer::where(['pcustID' => $give_customer->pcustID, 'activity_id' => $activity_id])->first();
            if ( empty( $customer_obj ) ) {
                $customer_obj = new JdCustomer();
                $customer_obj->uuid = makeUuid();
                $customer_obj->timeStamp = Carbon::now();
                $customer_obj->creator = 'system';
                $customer_obj->createTime = Carbon::now();
                $customer_obj->pcustID = $give_customer->pcustID;
                $customer_obj->custID = $give_customer->custID;
                $customer_obj->activity_id = $activity_id;
                $customer_obj->used_num = 0;
            }
            $customer_obj->total_num += $give_num;
            $customer_obj->not_used_num += $give_num;
            $customer_obj->save();


            //转赠记录
            JdCustomerDonation::insert([
                'uuid' => makeUuid(),
                'timeStamp' => Carbon::now(),
                'creator' => 'system',
                'createTime' => Carbon::now(),
                'activity_id' => $activity_id,
                'pcustID' => $pcust_id,
                'custID' => $cust_id,
                'donationPcustID' => $give_customer->pcustID,
                'donationCustID' => $give_customer->custID,
                'donation_num' => $give_num,
                'message' => $give_message
            ]);

            //提交事务
            DB::commit();

            //发送短信通知转赠对象
            if ( $give_message ) {

            }

        } catch (\Exception $e) {

            //事务回滚
            DB::rollBack();
            LockingService::remove();
            return response()->json(['code' => 10012 , 'message' => '集点转赠失败']);

        }

        //会员剩余集点数
        $not_used_num = $customer->not_used_num - $give_num;

        LockingService::remove();

        return response()->json(['code' => 200 , 'message' => '转赠成功' , 'data' => ['not_used_num' => app_to_int( $not_used_num ) ] ]);

    }

    /**
     * 奖品页
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function prize( Request $request )
    {

        $activity_id = $request->input('id',0);
        $platform = $request->input('platform',6);
        $session_id = $request->input('session_id');
        if ( !$session_id ) {
            $session_id = session_id();
            if (empty($session_id)) {
                return response()->json(['code' => 10000, 'message' => '缺少参数：session_id']);
            }
        }

        if ( !ebsig_is_int( $activity_id ) ) {
            return response()->json(['code' => 10001 , 'message' => '缺少活动id']);
        }

        //查询会员信息
        $pcust_id = get_customer_id( $session_id , $platform );

        $jd_cache = Jd::getCache( $activity_id );
        if ( empty( $jd_cache ) ) {
            return response()->json(['code' => 10002 , 'message' => '活动不存在']);
        }

        $have_num = 0;
        $state = 1;         //活动状态  0、未开始  1、进行中  2、已结束

        if ( $jd_cache['useFlg'] == 0  || $jd_cache['end_time'] < Carbon::now() ) {
            $state = 2;
        } else if ( $jd_cache['start_time'] > Carbon::now() ) {
            $state = 0;
        }

        if ( $pcust_id && $state ) {
            $customer = JdCustomer::where(['activity_id'=>$activity_id,'pcustID'=>$pcust_id])->first();
            if ( $customer  ) {
                $have_num = $customer->not_used_num;
            }
        }

        $prize = [];        //活动奖品
        $hav_prize = [];    //会员拥有奖品

        //查询活动奖品
        $prize_data = JdPrize::getCache( $activity_id );
        if ( $prize_data ) {
            foreach ( $prize_data as $item ) {

                /**
                 * 检查卡券信息
                 */
                $card_data = CardCoupon::find( $item['card_id'] );
                if ( !$card_data ) {
                    continue;
                }

                if ( !$card_data->useFlg ) {
                    continue;
                }

                $prize[$item['card_id']] = [
                    'discount' => app_to_float( $card_data['discount']*10 ),
                    'amount' => app_to_float( floatval( $card_data['amount'] ) ),
                    'card_type' => app_to_int( $card_data['card_type'] ),
                    'use_start_time' => date('Y.m.d',strtotime($card_data['start_time'])),
                    'use_end_time' => date('Y.m.d',strtotime( $card_data['end_time'] )),
                    'description' => $card_data['description'],
                    'limit_money' => app_to_float( $card_data['limit_money'] ),
                    'card_name' => $item['card_name']
                ];

            }
        }

        //查询已拥有的奖品
        if ( $pcust_id && $state ) {
            $customer_card = JdCustomerCard::where(['activity_id'=>$activity_id,'pcustID'=>$pcust_id])->get()->toArray();
            if ( $customer_card ) {
                foreach ( $customer_card as $item ) {
                    if ( isset( $prize[$item['card_id']] ) ) {
                        $hav_prize[] = $prize[$item['card_id']];
                    }
                }
            }
        }

        //组装返回数据
        $data = [
            'id' => app_to_int( $activity_id ),
            'name' => $jd_cache['activity_name'],
            'jd_num' => app_to_int( $jd_cache['jd_num'] ),
            'have_num' => app_to_int( $have_num ),
            'prize_explain' => app_to_string(nl2br($jd_cache['prize_explain'])),
            'state' => app_to_int($state),
            'start_time' => app_to_string($jd_cache['exchange_start_time']),
            'end_time' => app_to_string($jd_cache['exchange_end_time']),
            'prize' => $prize,
            'hav_prize' => $hav_prize
        ];

        return response()->json(['code' => 200 , 'message' => 'ok' , 'data' => $data ]);

    }

    /*
    * 兑换礼包
    */
    public function packageExchange ( Request $request ) {

        $activity_id = $request->input('id',0);
        $platform = $request->input('platform',6);
        $session_id = $request->input('session_id');
        if ( !$session_id ) {
            $session_id = session_id();
            if (empty($session_id)) {
                return response()->json(['code' => 10000, 'message' => '缺少参数：session_id']);
            }
        }

        if ( !ebsig_is_int( $activity_id ) ) {
            return response()->json(['code' => 10002 , 'message' => '缺少活动id']);
        }

        //查询会员信息
        $cust_data = get_customer_login( $session_id , $platform );
        $pcust_id = $cust_data['pcustID'];
        $cust_id = $cust_data['custID'];
        if ( !$pcust_id ) {
            return response()->json(['code' => 10001 , 'message' => '未登录']);
        }

        $jd_cache = Jd::getCache( $activity_id );
        if ( empty( $jd_cache ) ) {
            return response()->json(['code' => 10003 , 'message' => '活动不存在']);
        }
        if ( $jd_cache['useFlg'] == 0 ) {
            return response()->json(['code' => 10004 , 'message' => '活动被禁用']);
        }
        if ( $jd_cache['start_time'] > Carbon::now() ) {
            return response()->json(['code' => 10005 , 'message' => '活动未开始']);
        }
        if ( $jd_cache['end_time'] < Carbon::now() ) {
            return response()->json(['code' => 10005 , 'message' => '活动已结束']);
        }

        //加锁redis
        $redis_index = 'WDH_JD_LOCK_' . $activity_id . '_' . $pcust_id;
        if ( LockingService::check( $redis_index ) ) {
            return response()->json(['code' => 10020 , 'message' => '请求频繁']);
        }

        //查询拥有可用点数
        $customer = JdCustomer::where(['activity_id'=>$activity_id,'pcustID'=>$pcust_id])->first();
        if ( empty( $customer ) ) {
            LockingService::remove();
            return response()->json(['code' => 10007 , 'message' => '您还没有兑换点数' ]);
        }

        //判断拥有点数是否满足兑换条件
        if ( $customer->not_used_num < $jd_cache['jd_num'] ) {
            LockingService::remove();
            return response()->json(['code' => 10008 , 'message' => '您的兑换点数不足' ]);
        }

        //判断奖品是否可以继续领取
        $receive_num = Jd::getReceiveNum( $activity_id );
        if ( $receive_num < 0 || $receive_num >= $jd_cache['prize_num'] ) {
            LockingService::remove();
            return response()->json(['code' => 10009 , 'message' => '您来晚了，卡券已兑完' ]);
        }

        //查询奖品
        $prize_data = JdPrize::getCache( $activity_id );
        if ( empty( $prize_data ) ) {
            LockingService::remove();
            return response()->json(['code' => 10010 , 'message' => '奖品卡券不存在' ]);
        }

        //实例卡券服务类
        $card_service = new CardService();

        try {

            //开始事务
            DB::beginTransaction();

            //更新会员拥有点数
            $where = [
                ['activity_id','=',$activity_id],
                ['pcustID','=',$pcust_id],
                ['not_used_num','>=',$jd_cache['jd_num']]
            ];
            $result = JdCustomer::where($where)->decrement('not_used_num',$jd_cache['jd_num']);
            if ( !$result ) {
                throw new \Exception('集点扣除失败', 400);
            }

            //更新活动主表领取人数
            $update_num = Jd::updateReceiveNum( $activity_id );
            if ( $update_num < 0 ) {
                throw new \Exception('更新领取人数失败', 400);
            }

            Jd::where('activity_id',$activity_id)->increment('receive_num');

            foreach ( $prize_data as $prize ) {

                /*
                 * 查询卡券信息
                */
                $card_data = CardCoupon::find( $prize['card_id'] );
                if ( empty( $card_data ) ) {
                    throw new \Exception($prize['card_name'].'卡券不存在', 10011);
                } else {
                    $card_data = $card_data->toArray();
                }

                if ( $card_data['provide_type'] != 1 ) {
                    throw new \Exception($prize['card_name'].'卡券不是账户券，无法发放', 10012);
                }

                if ( $card_data['start_time'] > Carbon::now() || $card_data['end_time'] < Carbon::now() ) {
                    throw new \Exception($prize['card_name'].'卡券不在发放时间范围内', 10013);
                }

                if ( !$card_data['useFlg'] ) {
                    throw new \Exception( $prize['card_name'].'卡券被禁用', 10014);
                }

                if ( $card_data['repeat_count'] > 0 ) {
                    $search_num =  CardCouponCode::where(['activity_id'=>$card_data['card_id'],'pcustID'=>$pcust_id])->count();
                    if ( $search_num >=  $card_data['repeat_count']  ) {
                        throw new \Exception( $prize['card_name'].'卡券已超出重复领取次数', 10015);
                    }
                }

                //判断剩余卡券数
                if ( $card_data['getNum'] >= $card_data['total_num'] ) {
                    throw new \Exception( $prize['card_name'].'卡券数量不足', 10016);
                }

                //判断活动库存数是否大于卡券数量
                if ( $prize['card_num'] > ( $card_data['total_num'] - $card_data['getNum'] ) ) {
                    throw new \Exception( $prize['card_name'].'卡券数量不足', 10017);
                }

                //循环发放卡券
                for ( $i = 0 ; $i < $prize['card_num'] ; $i++ ) {

                    //发放卡券
                    $send_result = $card_service->grant( $card_data , 1 , $pcust_id , $cust_id , false );
                    if ( $send_result['code'] != 200 ) {
                        throw new \Exception( $send_result['message'] , 10018);
                    }

                    //保存兑换记录
                    $exchange_id = JdCustomerExchange::insertGetId([
                        'uuid' => makeUuid(),
                        'timeStamp' => Carbon::now(),
                        'creator' => 'system',
                        'createTime' => Carbon::now(),
                        'activity_id' => $activity_id,
                        'pcustID' => $pcust_id,
                        'custID' => $cust_id,
                        'used_num' => $jd_cache['jd_num']
                    ]);

                    //保存兑换卡券
                    JdCustomerCard::insert([
                        'uuid' => makeUuid(),
                        'timeStamp' => Carbon::now(),
                        'creator' => 'system',
                        'createTime' => Carbon::now(),
                        'activity_id' => $activity_id,
                        'pcustID' => $pcust_id,
                        'custID' => $cust_id,
                        'exchange_id' => $exchange_id,
                        'card_id' => $prize['card_id']
                    ]);

                }

            }

            JdCustomer::where(['activity_id'=>$activity_id,'pcustID'=>$pcust_id])->increment('used_num',$jd_cache['jd_num']);




            //提交事务
            DB::commit();

        } catch ( \Exception $e) {

            //事务回滚
            DB::rollBack();

            LockingService::remove();

            if ( $e->getCode() > 0) {
                return response()->json(['code' => $e->getCode() , 'message' => $e->getMessage() ]);
            } else {
                return response()->json(['code' => 10019 , 'message' => '卡券兑换失败' ]);
            }

        }

        return response()->json(['code' => 200 , 'message' => '卡券兑换成功' ]);

    }

}